#include "android_env.h"

jobject mCallbackObj;
static jclass mCallbackClass;


/**
 * 获取对象实例
 */
static int getJavaCallbackInstance(JNIEnv *jniEnv, jclass obj_class)
{
    jmethodID getInstanceMethod;
    jobject emvNative_tmp;

    getInstanceMethod = (*jniEnv)->GetStaticMethodID(jniEnv, obj_class, "getInstance",
                                                     "()Lcom/trendit/classicpos/callback/JavaCallback;");
    emvNative_tmp = (*jniEnv)->CallStaticObjectMethod(jniEnv, obj_class, getInstanceMethod);
    mCallbackObj = (*jniEnv)->NewGlobalRef(jniEnv, emvNative_tmp);
    if (mCallbackObj == NULL)
    {
        return -2;
    }
    return 0;
}

/**
 * 初始化 类、对象
 */
static int javaCallbackInit(JNIEnv *jniEnv)
{
    jclass tmp_class;

    if (jniEnv == NULL)
    {
        return -1;
    }
    if (mCallbackClass == NULL)
    {
        tmp_class = (*jniEnv)->FindClass(jniEnv,
                                         "com/trendit/classicpos/callback/JavaCallback");
        if (tmp_class == NULL)
        {
            return -1;
        }
        mCallbackClass = (*jniEnv)->NewGlobalRef(jniEnv, tmp_class);
        if (mCallbackClass == NULL)
        {
            return -2;
        }
    }

    if (mCallbackObj == NULL)
    {
        if (getJavaCallbackInstance(jniEnv, mCallbackClass) < 0)
        {
            (*jniEnv)->DeleteLocalRef(jniEnv, mCallbackClass);
            return -3;
        }
    }
    return 0;
}


static int initCallback(JNIEnv *env)
{
    if (mCallbackClass == NULL || mCallbackObj == NULL)
    {
        int result = javaCallbackInit(env);
        if (result < 0)
        {
            LOG("Fail to find javaClass or object result = %d", result);
            return result;
        }
    }

    return 0;
}


JNIEnv *initJavaCallbackMethod(jmethodID *method, const char *method_name, const char *method_params, int *detach)
{
    JNIEnv *env = getEnvInfo(detach);
    if (env == NULL)
    {
        return NULL;
    }

    if (initCallback(env) < 0)
    {
        LOG("check_env error !!! ");
        detach_thread(*detach);
        return NULL;
    }

    *method = (*env)->GetMethodID(env, mCallbackClass, method_name, method_params);
    if (*method == NULL)
    {
        LOG("get JMethodID1 error !!!");
        detach_thread(*detach);
        return NULL;
    }
    return env;
}

void freeGlobalJObject(JNIEnv *jniEnv)
{
    (*jniEnv)->DeleteGlobalRef(jniEnv, mCallbackClass);
    (*jniEnv)->DeleteGlobalRef(jniEnv, mCallbackObj);
    mCallbackClass = NULL;
    mCallbackObj = NULL;
}
